package notes.java.juc.demo;

/**
 * 问题的引入：
 * 1、启动子一个线程将flag变为true
 * 2、主线程一直判断这个flag是否为true ，如果为true打印并终止
 * 
 *  结果尽然不行。
 *  原因 ： 内存可见性问题，当多个操作时彼此不可见。while是java底层的，速度非常快，没时间 来读取tt.flag的值是否发生变化
 *  修改：
 *  	法1、添加Thread.sleep(1000); 让while循环慢点。
 *      法2、添加synchronized
 *      法3、加volatile关键字，多个线程操作时，保证共享数据是可见的
 *          volatile不具备互斥性
 *          volatile不能保证变量的原子性
 */
public class J1_TestVolatile {
	
	public static void main(String[] args) throws InterruptedException {
		
		// 启动子一个线程将flag变为true
		TestThread tt = new TestThread();
		new Thread(tt).start();
		
		// 主线程一直判断这个flag是否为true ，如果为true打印并终止
		while(true) {
			// 法1、Thread.sleep(1000);
			// 法2、加synchronized
//			synchronized (tt) {
//				if(tt.isFlag() == true) {
//					System.out.println("-------------------");
//					break;
//				}
//			}
			
			if(tt.isFlag() == true) {
				System.out.println("-------------------");
				break;
			}
		}
	}
	

}

// 一个线程将flag 变为true
class TestThread implements Runnable {
	private boolean flag = false;
	
	// 法3 加volatile关键字，保证内存中的数据可见性
	//private volatile boolean flag = false;
	
	@Override
	public void run() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		this.flag = true;
		System.out.println("子线程已经将flag修改为true了！");
	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}
}
